// === uuAltCSS.calcspec ===
// depend: uuAltCSS
// http://www.w3.org/TR/css3-selectors/#specificity
(function() {
var _calcspec, // inner namespace
    SPEC_E = /\w+/g,
    SPEC_ID = /#[\w\u00C0-\uFFEE\-]+/g, // (
    SPEC_NOT = /:not\(([^\)]+)\)/,
    SPEC_ATTR =
        /\[\s*(?:([^~\^$*|=\s]+)\s*([~\^$*|]?\=)\s*(["'])?(.*?)\3|([^\]\s]+))\s*\]/g,
    SPEC_CLASS = /\.[\w\u00C0-\uFFEE\-]+/g,
    SPEC_PCLASS = /:[\w\-]+(?:\(.*\))?/g,
    SPEC_PELEMENT = /::?(?:first-letter|first-line|before|after)/g,
    SPEC_CONTAINS = /:contains\((["'])?.*?\1\)/g;

// uuAltCSS.calcspec - Calculating a selector's specificity
_calcspec = function(expr) { // @param String: simple selector(without comma)
                             // @return Number: spec value
  function A() { ++a; return ""; }
  function B() { ++b; return ""; }
  function C() { ++c; return ""; }
  function C2(m, E) { return " " + E; }

  var a = 0, b = 0, c = 0;

  expr.replace(SPEC_NOT, C2).      // :not(E)
       replace(SPEC_ID, A).        // #id
       replace(SPEC_CLASS, B).     // .class
       replace(SPEC_CONTAINS, B).  // :contains("...")
       replace(SPEC_PELEMENT, C).  // ::pseudo-element
       replace(SPEC_PCLASS, B).    // :pseudo-class
       replace(SPEC_ATTR, B).      // [attr=value]
       replace(SPEC_E, C);         // E
  // ignore the universal selector

  return a * 100 + b * 10 + c;
};

// --- initialize ---

// --- export ---
window.uuAltCSS.calcspec = _calcspec;

})(); // uuAltCSS.calcspec scope

